import type { App } from '@vue/runtime-core'
import { useRoute } from 'vue-router'
import type { Router } from 'vue-router'
import { Store } from 'vuex'
import { http } from 'justom-share'
import type { RootState } from './store/types'
import createAuthShowDirective from '@/directives/authShow'
import createHasPermiDirective from '@/directives/hasPermi'
import createTableColumnShowDirective from '@/directives/tableColumnShow'
import type { PermissionSearch } from '@/store/modules/auth'
import { ElNotification, ElMessage } from 'element-plus'
import httpRequest from '@/public/request'
// import mediator from "./websocket";
// import signalr from "./websocket/signalr";
// import sg from "./websocket/sg.js";
import SignalR from './websocket/signalr.js'

interface Components {
  app: App
  router: Router
  store: Store<RootState>
  httpInstance: http.AxiosRequest
}
// 前端版本号
const WEB_VERSION = 1
/**
 * axios 拦截器
 * @param components
 */
function axiosInterceptors(components: Components) {
  const { httpInstance, store, router } = components
  // http
  // 将每次请求都附上 jwt token
  httpInstance.axios.interceptors.request.use(
    (config) => {
      let token = store.state.auth.token
      config.headers['jst-web-version'] = WEB_VERSION
      config.headers['Authorization'] = token ?? 'Bearer '
      return config
    },
    (err) => {
      return Promise.reject(err)
    }
  )
  // response
  httpInstance.axios.interceptors.response.use(
    function (response) {
      return response
    },
    async function (error) {
      switch (error.response && error.response.status) {
        case 401:
          store.dispatch('auth/logout')

          // 如果 未匹配到路由 或者是 标记了allowLogout的路由 不弹出登出
          if (
            router.currentRoute.value.matched.length == 0 ||
            router.currentRoute.value.meta.allowLogout
          ) {
            // 如果当前界面允许未登录访问 不进行任何操作
            return
          }

          if (store.state.AccountMode === 'employee') {
            router.push('/employeeLogin')
          } else {
            // 出现401 打回到登录界面
            // ElMessage.warning('登录凭证已过期')
            ElMessage({
              customClass: 'comments-401-warning',
              message: '登录凭证已过期',
              grouping: true,
              type: 'warning'
            })
            router.push({
              path: '/'
            })
          }

          break
        case 409:
          // 409 Conflict 打回到首页登录界面  (只允许一个账号同时登录)
          router.push({
            path: '/',
            query: {
              showConflict: true
            }
          })
          break
        case 403:
          // 查看是否有新的token写入
          for (let key in error.response.headers) {
            if (key.toLocaleLowerCase() == 'loginaccesstoken') {
              await store.dispatch(
                'auth/setTokenAndGetInfo',
                error.response.headers[key]
              )
              break
            }
          }
          break
        case 500:
          ElMessage.error(`接口错误：${error.response.data.message}`)
          break
      }

      return Promise.reject(error)
    }
  )
}

/**
 * 路由守护
 * @param components
 */
function routerGuard(components: Components) {
  const { router, store } = components

  // router
  router.beforeEach(async (to, from, next) => {
    // 修改标题
    document.title = `${to.meta.title ?? ''} - ${store.state.systemName}`
    next()
  })

  /**
   * 菜单 404 / 403 验证
   */
  router.beforeEach(async (to, from, next) => {
    // 没有匹配到界面 跳转到404
    if (to.matched.length == 0) {
      // 判断是不是内部的页面
      if (from.matched.find((t) => t.name == 'internal')) {
        next({
          path: '/internal/404',
          query: {
            url: to.fullPath
          }
        })
      } else {
        next({
          path: '/manageLogin'
          // query: {
          //   showLogin: true,
          // },
        })
      }
    }
    next()
  })
}

/**
 * 业务权限全局方法
 * @param components
 */
function addPermissionFunc(components: Components) {
  const { app, store } = components
  app.config.globalProperties.$permission = function (
    target: PermissionSearch
  ): string | null {
    return store.getters['auth/getPermission'](target)
  }
}

/**
 *  组合/关联 各个组件
 * @param app
 * @param router
 * @param store
 * @param httpInstance
 */
export default function composition(components: Components) {
  // router
  routerGuard(components)
  // http
  axiosInterceptors(components)
  // 添加 业务权限 全局方法
  addPermissionFunc(components)
  // v-auth-show
  createAuthShowDirective(components.app, components.store, components.router)
  //v-hasPermi
  createHasPermiDirective(components.app, components.store)
  //v-tableColumnShow
  createTableColumnShowDirective(components.app, components.store)

  let host = import.meta.env.VITE_WEB_SOCKET
  // "http://localhost:8002/chatHub?userid=1"

  //ws添加当前登录的用户的id，用于消息的提示
  httpRequest
    .get('/auth/info')
    .then((userInfo) => {
      host = host + '?userid=' + userInfo.user.id
    })
    .finally(() => {
      SignalR.initialize(host)
      SignalR.on('ReceiveMessage', (message) => {
        components.store.dispatch('unReadMessage/getUnReadMessageData')
        ElNotification({
          title: 'success',
          message: message,
          type: 'success'
        })
      })
    })

  //let host = import.meta.env.VITE_WEB_SOCKET as string
  // SignalR.initialize(host);
  //   SignalR.on("ReceiveMessage", (message) => {
  //       console.log(message,"message");
  //   });
  // 接收消息推送
  // signalr.event.on("onMessage", (msg) => {
  //   if (msg.type == "message/send") {
  //     // 刷新消息数量
  //     components.store.dispatch("message/getMessageCount")
  //     httpRequest.get("/api/Message/GetMessageSelfInfoDetail", {
  //       id: msg.content
  //     }).then(async (res) => {
  //       if (res.Status == false) {
  //         return;
  //       }
  //       let msg = res.Data;

  //       ElNotification({
  //         type: "info",
  //         title: msg.Title,
  //         message: msg.Description,
  //         onClick() {
  //           components.router.push({
  //             path: "/system/messageDetail",
  //             query: {
  //               id: msg.SendId
  //             }
  //           })
  //         }
  //       })
  //     })
  //   }
  // })

  // signalr.event.on("onReConnect", () => {
  //   // 触发获得当前员工信息 重新设置token
  //   components.store.dispatch("auth/getCurrentEmployeeInfo")
  // });
}
